package transporte.server.seguridad.aspect;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import transporte.server.seguridad.NoPrivsException;
import transporte.server.seguridad.RequirePrivs;
import transporte.web.seguridad.SeguridadController;

@Component
@Aspect
public class VerificarPrivsAspect {

	@Around("bean(*Controller*) && @annotation(requirePrivs)")
	public Object validarPrivs(ProceedingJoinPoint pjp, RequirePrivs requirePrivs) throws Throwable {
		
		HttpSession session = VerificarPrivsInterceptor.getSession();
		if (session == null || session.getAttribute(SeguridadController.LOGGED_USER) == null) {
			throw new NoPrivsException();
		}

		if (isValid(pjp, requirePrivs, session)) {		
			return pjp.proceed();
		} else {
			throw new NoPrivsException();
		}
	}

	private boolean isValid(ProceedingJoinPoint pjp, RequirePrivs requirePrivs, HttpSession session) {
		String[] privNamesToVerify = requirePrivs.privs();
		
		// If there are no privs to verify, then validate the user is logged
		if (privNamesToVerify == null || privNamesToVerify.length == 0) {
			return session.getAttribute(SeguridadController.LOGGED_USER) != null;
		}
		
		boolean privsValid = true;
		
		Map<String, Boolean> privManager = (Map<String, Boolean>) session.getAttribute(SeguridadController.PRIV_MANGER);
		
		for(String priv : privNamesToVerify) {				

			if (!Boolean.TRUE.equals(privManager.get(priv))) {
				privsValid = false;
				if (requirePrivs.allRequired()) break;
			} else {
				privsValid = true;
				if (!requirePrivs.allRequired()) break;
			}
		}
		return privsValid;
    }
	
}
